﻿using System.Collections.Generic;
using Newtonsoft.Json.Linq;

namespace DingTalk.Common
{
    namespace Extensions
    {
        public static class JsonHelperExtension
        {
            /// <summary>
            /// json数据解析字典数据
            /// </summary>
            /// <param name="keyHeadName">键头</param>
            /// <param name="key">键</param>
            /// <param name="targetJToken">json源数据</param>
            /// <param name="arrayStartIndex">数组索引</param>
            /// <param name="dic">字典</param>
            /// <param name="depth">深度</param>
            /// <returns></returns>
            public static Dictionary<string, object> GetDictionary(Dictionary<string, object> dic, string keyHeadName, JToken targetJToken, string key = null,
                int arrayStartIndex = 0, int depth = -2)
            {
                if (depth + 1 == 0) return dic;
                foreach (var token in targetJToken)
                {
                    if (targetJToken.Type.Equals(JTokenType.Array))//json数组
                    {
                        var jArray = targetJToken.ToObject<JArray>();
                        var pathKey = key + arrayStartIndex++;
                        if (token.Type.Equals(JTokenType.String) || token.Type.Equals(JTokenType.Integer) ||
                            token.Type.Equals(JTokenType.Float))//JValue
                        {
                            var jValue = token.ToObject<JValue>();
                            var val = jValue?.Value;
                            dic.Add(keyHeadName + ":" + pathKey, val);
                            continue;
                        }
                        else//非JValue
                        {
                            GetDictionary(dic, keyHeadName, token, pathKey, 0, depth - 1);
                        }
                    }
                    else//非json数组
                    {
                        var jProperty = token.ToObject<JProperty>();
                        var pathKey = key == null ? jProperty?.Name : key + "." + jProperty?.Name;
                        if (jProperty.Value.Type.Equals(JTokenType.String) || jProperty.Value.Type.Equals(JTokenType.Integer) ||
                            jProperty.Value.Type.Equals(JTokenType.Float))//JValue
                        {
                            var jValue = jProperty.Value.ToObject<JValue>();
                            var val = jValue?.Value;
                            dic.Add(keyHeadName + ":" + pathKey, val);
                            continue;
                        }
                        else//非JValue
                        {
                            GetDictionary(dic, keyHeadName, jProperty.Value, pathKey, 0, depth - 1);
                        }
                    }
                }

                return dic;
            }

            /// <summary>
            /// json数据解析字典数据
            /// </summary>
            /// <param name="keyHeadName">键头</param>
            /// <param name="currentJToken">目标json对象</param>
            /// <param name="dic">字典</param>
            /// <param name="depth">小于-1全遍历</param>
            /// <returns></returns>
            public static Dictionary<string, object> GetDictionary(string keyHeadName, JToken currentJToken,
                Dictionary<string, object> dic, int depth = -2)
            {
                var key = keyHeadName;
                if (depth + 1 == 0) return dic;
                foreach (var jsonValue in currentJToken)
                {
                    if (jsonValue.Type.Equals(JTokenType.String) || jsonValue.Type.Equals(JTokenType.Integer) ||
                        jsonValue.Type.Equals(JTokenType.Float))
                    {
                        var jValue = jsonValue.ToObject<JValue>();
                        key = keyHeadName + ":" + jsonValue.Path.Replace("[", "")
                            .Replace("]", "");
                        dic.Add(key, jValue?.Value);
                        continue;
                    }
                    else
                    {
                        dic = GetDictionary(key, jsonValue, dic, depth - 1);
                    }
                }

                return dic;
            }
        }
    }
}
